/** ***********************************************************************************
* @file         save_task.h
* @brief        数据存储处理任务
* @details      主要用来处理发送的数据进行数据存现
* @author       杨小珛
* @date         2021/3/7
* @copyright    北京高知科技有限公司    
* @version      V1.0
* @attention    无
**************************************************************************************/

#ifndef SAVE_TASK_H
#define SAVE_TASK_H

#include "os_app.h"
#include "flash_buffer.h"
#include "flash_config.h"

/****************************************************************************************
* SAVE RAM 空间数据结构体
******************************************************************************************/
/* RAM最大申请的条目数量10包数据，第1包数据用来存储最新一包数据，最后12包数据用来向FLASH存储数据*/
#define SAVE_RAM_DATA_MAX_NUM   ( 12 )  
#define SAVE_RAM_OPEN_MAX_NUM   ( 5  )  /* RAM被打开的最大数量 */

#define SAVE_RAM_DATA_NUM ( 10 )        /* RAM数据缓存的空间*/

typedef  struct
{
    sfb_buf_rt_t *sfb_handle;    /* FLASH 的句柄 */
    uint32_t handle_num;         /* handle 句柄存储的位置*/
    union                                          
    {
        uint32_t ram_num;        /* RAM空间数据标识*/
        struct
        {
            uint32_t head_flag  : 1;    /* 1 有数据 0 没有数据 */  
            uint32_t cache_len : 30 ;   /* 缓存空间中的数据长度，可以缓存 SAVE_RAM_DATA_NUM 长度*/
            uint32_t tail_flag  : 1 ;   /* 1 有数据 0 没有数据 */ 
        };
    };
    uint8_t  *ram_buf;           /* 动态申请RAM空间地址 */
}save_ram_data_infor_t;

/****************************************************************************************
* SAVE FLASH 空间数据结构体
******************************************************************************************/
#define SAVE_DATA_QUEUE_DEPTH           ( 10 )
#define SAVE_DATA_WAIT_TIME             ( 5000 )
#define SAVE_DATA_FALSH_WRITE_TIME      ( 100 )
typedef  struct
{
    volatile uint32_t handle_id;
    volatile uint32_t len;
    volatile uint8_t *data;
}save_data_infor_t;

/****************************FLASH数据读写状态**************************/
typedef enum
{
	SAVE_DATA_WRITE =0x00,        /* 写数据 */
	SAVE_DATA_READ,               /* 读数据 */
}save_data_mode_e;

/****************************存储数据FLASH状态**************************/
typedef enum
{
	SAVE_DATA_FLASH_ERR =0x00,   
	SAVE_DATA_FLASH_OK,       
}save_data_flash_state_e;

/***************************存储MCU关键信息数据***************************/
#define MCU_DATA_BLOCK_SIZE ( 64 )  /*结构体得数据长度必须为64个字节*/
#define MCU_DATA_INFOR_SIZE ( 56 )  /*消息内容的长度*/

#pragma pack(1)
typedef  struct 
{
    volatile uint32_t period;       /*写入得周期次数*/
    volatile uint16_t once;         /*单个周期内得位置*/
    volatile uint8_t  len;          /*写入数据得长度*/
    volatile uint8_t  data[MCU_DATA_INFOR_SIZE];
    volatile uint8_t  crc;          /*CRC数据校验*/
}save_mcu_data_infor_t;
#pragma pack()

/** ****************************************************************************
* @remarks       void save_data_create_task( unsigned portBASE_TYPE uxPriority )
* @brief         数据存储管理任务
* @param[in]     uxPriority任务优先级；
* @param[out]    无
* @return        无
* @attention     在系统启动后进行创建
*******************************************************************************/
extern void save_data_create_task( unsigned portBASE_TYPE uxPriority );

/** ****************************************************************************
* @remarks       void save_data_bbt_tables_init( void )
* @brief         初始数据存储空间
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void save_data_bbt_tables_init( void );

/** ****************************************************************************
* @remarks       save_data_flash_state_e save_data_flash_state_get( void )
* @brief         获取FLASH 状态
* @param[in]     无
* @param[out]    无
* @return        返回FLASH的工作状态 SAVE_DATA_FLASH_ERR：失败 SAVE_DATA_FLASH_OK：成功
* @attention     无
*******************************************************************************/
extern save_data_flash_state_e save_data_flash_state_get( void );

/** ****************************************************************************
* @remarks       uint32_t save_data_open( sfb_buf_rt_t *sfb_handle ,const sfb_setting_t *sfb_set , uint32_t *handle_id )
* @brief         打开SAVE 数据，进行初始
* @param[in]     *handle_id 句柄地址id
* @param[in]     *sfb_set SFB设置的地址参数
* @param[out]    无
* @return        pdPASS 成功 pdFAIL 失败
* @attention     必须在任务中运行
*******************************************************************************/
extern uint32_t save_data_open( sfb_buf_rt_t *sfb_handle ,const sfb_setting_t *sfb_set , uint32_t *handle_id );

/** ****************************************************************************
* @remarks       uint32_t save_data_write( uint32_t handle_id ,uint8_t *data, uint16_t dlen )
* @brief         写FLASH 数据
* @param[in]     handle_id 句柄ID
* @param[in]     *data 保存的数据地址
* @param[in]     dlen 保存的数据长度
* @param[out]    无
* @return        pdPASS 成功 ， pdFAIL 失败
* @attention     可重入函数 内部互斥
*******************************************************************************/
extern uint32_t save_data_write( uint32_t handle_id ,uint8_t *data, uint16_t dlen );

/** ****************************************************************************
* @remarks       uint32_t save_data_read( uint32_t handle_id ,uint8_t *data, uint16_t *dlen )
* @brief         读FLASH 数据
* @param[in]     handle_id SAVE句柄ID
* @param[out]    *data 数据的目标地址
* @param[out]    *dlen 数据的长度
* @return        返回 数据包的长度 等于0时没有数据
* @attention     可重入函数 内部互斥
*******************************************************************************/
extern uint32_t save_data_read( uint32_t handle_id ,uint8_t *data, uint16_t *dlen );

/** ****************************************************************************
* @remarks       uint32_t save_data_close( uint32_t handle_id )
* @brief         关闭FLASH 句柄操作
* @param[in]     handle_id SAVE句柄id
* @param[out]    无
* @return        pdPASS  成功 ， pdFAIL  失败
* @attention     可重入函数 内部互斥
*******************************************************************************/
extern uint32_t save_data_close( uint32_t handle_id );

/** ****************************************************************************
* @remarks       uint32_t save_mcu_data_infor_init( void )
* @brief         MCU关键信息初始化，主要就是用来读取当前最新的数据。
* @param[in]     无
* @param[out]    无
* @return        pdPASS 成功，pdFAIL 失败；
* @attention     无
*******************************************************************************/
extern uint32_t save_mcu_data_infor_init( void );

/** ****************************************************************************
* @remarks       uint32_t save_mcu_data_infor_write( uint8_t *data, uint8_t len )
* @brief         写MCU关键性数据信息
* @param[in]     *data 数据源地址
* @param[out]    *dlen 数据长度
* @return        pdPASS 成功，pdFAIL 失败；
* @attention     无
*******************************************************************************/
extern uint32_t save_mcu_data_infor_write( uint8_t *data, uint8_t dlen );

/** ****************************************************************************
* @remarks       uint32_t save_mcu_data_infor_read( uint8_t *data, uint8_t dlen )
* @brief         读取MCU关键性数据信息（最新的数据）
* @param[out]    *data 数据目标地址
* @param[out]    *dlen 数据长度
* @return        pdPASS 成功，pdFAIL 失败；
* @attention     无
*******************************************************************************/
extern uint32_t save_mcu_data_infor_read( uint8_t *data, uint8_t *dlen );

/** ****************************************************************************
* @remarks       uint32_t save_vin_data_infor_write( uint8_t *data, uint16_t dlen )
* @brief         写VIN关键性数据信息
* @param[in]     *data 数据源地址
* @param[in]    *dlen 数据长度
* @return        pdPASS 成功，pdFAIL 失败；
* @attention     无
*******************************************************************************/
extern uint32_t save_vin_data_infor_write( uint8_t *data, uint16_t dlen );

/** ****************************************************************************
* @remarks       uint32_t save_vin_data_infor_write( uint8_t *data, uint16_t dlen )
* @brief         读取VIN关键性数据信息
* @param[in]     dlen 读取数据长度
* @param[out]    *data 数据目标地址地址
* @return        pdPASS 成功，pdFAIL 失败；
* @attention     无
*******************************************************************************/
extern uint32_t save_vin_data_infor_read( uint8_t *data, uint16_t dlen );

/** ****************************************************************************
* @remarks       void save_data_sys_reset_write_flash( void )
* @brief         系统在复位时将RAM中的数据保存到外部FLASH中
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void save_data_sys_reset_write_flash( void );

/** ****************************************************************************
* @remarks       uint32_t save_reset_reason_write( uint8_t *data, uint16_t dlen )
* @brief         存储设备重启原因
* @param[in]     *data 数据源地址
* @param[in]    *dlen 数据长度
* @return        pdPASS 成功，pdFAIL 失败；
* @attention     无
*******************************************************************************/
extern uint32_t save_reset_reason_write( uint8_t *data, uint16_t dlen );

/** ****************************************************************************
* @remarks      uint32_t save_reset_reson_read( uint8_t *data, uint16_t dlen )
* @brief        读出设备的重启原因
* @param[in]     dlen 读取数据长度
* @param[out]    *data 数据目标地址地址
* @return        pdPASS 成功，pdFAIL 失败；
* @attention     无
*******************************************************************************/
extern uint32_t save_reset_reason_read( uint8_t *data, uint16_t dlen );

/** ****************************************************************************
* @remarks       uint32_t save_lbs_key_write_to_flash( uint8_t *data, uint16_t len )
* @brief         将LBS数据保存到FLASH中
* @param[in]     *data 数据源地址，len数据长度
* @param[out]    无
* @return        pdPASS 成功，pdFAIL 失败。
* @attention     数据长度不大于 4096 - 3 个字节；
*******************************************************************************/
extern uint32_t save_lbs_key_write_to_flash( uint8_t *data, uint16_t len );

/** ****************************************************************************
* @remarks       uint32_t save_lbs_key_read_form_flash( uint8_t *data, uint16_t *len )
* @brief         读取LBD FLASH中数据
* @param[in]     *len 源地址数据长度
* @param[out]    *data 数据源地址，*len数据长度
* @return        pdPASS 成功，pdFAIL 失败。
* @attention     读取得数据长度小于 4096 -3 个字节。
*******************************************************************************/
uint32_t save_lbs_key_read_form_flash( uint8_t *data, uint16_t *len );


#endif

